/**
 * @file    并机处理.c
 * @brief   
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-05-05
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-05-05 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "parallel.h"
#include "cfg_prj.h"
#include "var_mng.h"
#include "param_mng.h"
#include "If_di.h"
#include "sop_calc.h"
#include "pc_jbd.h"
#include "mcu_type.h"
#include "sample.h"
#include "If_do.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
typedef struct
{
	uint8_t cov_cnt;
	uint8_t cuv_cnt;
	uint8_t bov_cnt;
	uint8_t buv_cnt;
	uint8_t occ_cnt;
	uint8_t occ2_cnt;
	uint8_t ocd_cnt;
	uint8_t ocd2_cnt;
	uint8_t otc_cnt;
	uint8_t utc_cnt;
	uint8_t otd_cnt;
	uint8_t utd_cnt;	
	uint8_t otm_cnt;
	uint8_t ote_cnt;
	uint8_t ute_cnt;
	uint8_t vdiff_cnt;	
	uint8_t sc_cnt;
	uint8_t col_cnt;
	uint8_t tol_cnt;
	uint8_t afe_err_cnt;
	uint8_t fcmos_cnt;
	uint8_t fdmos_cnt;
}slave_prp_num_type;

/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/

/* global variables ----------------------------------------------------------*/
master_data_type master_data_reg = {0};
slave_ol_type slave_ol_data[CFG_PARALLEL_NUM] = {0}; /* 从机状态数据 */
static uint8_t dsg_en_flag = 1; /* 放电使能 */
static uint8_t chg_en_flag = 1; /* 充电使能 */
static uint8_t force_chg1 = 0;  /* 强充标志位1 */
static uint8_t force_chg2 = 0;  /* 强充标志位2 */

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
void parallel_master_update_self(void)
{
    float ftemp = 0;
    uint16_t i = 0;
    int32_t s_curr = 0;
	uint16_t soc = 0;

    master_data_reg.slave_data[0].cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
    for( i = 0;i < SLAVE_CELL_NUM; ++ i)
    {
        master_data_reg.slave_data[0].cell_volt_buf[i] = var_get_data(VAR_ID_CELL_VOLT01 + i);
    }
    master_data_reg.slave_data[0].max_cell_volt = var_get_data(VAR_ID_MAX_CELL_VOLT);
    master_data_reg.slave_data[0].min_cell_volt = var_get_data(VAR_ID_MIN_CELL_VOLT);
    master_data_reg.slave_data[0].batt_volt = var_get_data(VAR_ID_BATT_VOLT);
    ftemp = var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
    s_curr = ftemp * 100;
    master_data_reg.slave_data[0].curr_h16 = s_curr >> 16;
    master_data_reg.slave_data[0].curr_l16 = s_curr & 0xffff;
    ftemp = var_get_data(VAR_ID_MAX_TEMP_VAL) * 0.1 - 50;
    master_data_reg.slave_data[0].max_temp = (int32_t)((ftemp + 273.15f) * 10);
    ftemp = var_get_data(VAR_ID_MIN_TEMP_VAL) * 0.1 - 50;
    master_data_reg.slave_data[0].min_temp = (int32_t)((ftemp + 273.15f) * 10);
    master_data_reg.slave_data[0].full_cap = param_get_data(PAR_ID_FULL_CAP);
    master_data_reg.slave_data[0].real_cap = var_get_data(VAR_ID_DISP_RCAP);
    master_data_reg.slave_data[0].cycle = param_get_data(PAR_ID_CYCLE);
	soc = var_get_data(VAR_ID_DISP_SOC) * 0.01 + 0.99;  //+1？
	if(soc >= 100)
		soc = 100;
    master_data_reg.slave_data[0].soc = soc;
    master_data_reg.slave_data[0].soh = param_get_data(PAR_ID_SOH);
    master_data_reg.slave_data[0].prp_volt_status.prp_msg = parallel_get_volt_prp_msg();
    master_data_reg.slave_data[0].prp_temp_status.prp_msg = parallel_get_temp_prp_msg();
    master_data_reg.slave_data[0].fet_status = parallel_get_fet_status();
    master_data_reg.slave_data[0].alarm_status = parallel_get_alarm_status();
    for(i = 0;i < 15; ++ i)
    {
        master_data_reg.slave_data[0].sn_code[i] = param_get_data(PAR_ID_SN_CODE + i);
    }
    /* 要调换高低字节 所以版本号与最后一位调换 */
	master_data_reg.slave_data[0].sop_cc = var_get_data(VAR_ID_SOP_CC);
	master_data_reg.slave_data[0].sop_dc = var_get_data(VAR_ID_SOP_DC);
	master_data_reg.slave_data[0].ver_test = SOFT_VER_TEST;
	master_data_reg.slave_data[0].version = SOFT_VER_RELEASE;
	master_data_reg.slave_data[0].temp_num = param_get_data(PAR_ID_CB_TEMP_NUM);	
	for( i = 0;i < CFG_TEMP_NUM; ++ i)
	{
		master_data_reg.slave_data[0].cell_temp_buf[i] = var_get_data(VAR_ID_CELL_TEMP01 + i) + 2231;
	}
	master_data_reg.slave_data[0].mos_temp = var_get_data(VAR_ID_MOS_TEMP) + 2231;
	master_data_reg.slave_data[0].env_temp = var_get_data(VAR_ID_ENV_TEMP) + 2231;
	slave_ol_data[0].ol_state = 1;
 //   master_data_reg.slave_data[0].sign_msg = parallel_get_sys_sign_msg();	
}    

void parallel_slave_update_self(uint16_t cycle)
{
    float ftemp = 0;
    uint16_t i = 0;
    int32_t s_curr = 0;
	uint8_t addr = 0;
	uint8_t j = 0;
	static uint16_t updata_cycle = 0;
	uint8_t fet_status = 0;
	uint16_t v16_temp = 0;
	
	updata_cycle += cycle;
	
	if(updata_cycle < 1000)
		return ;
	
	updata_cycle = 0;
		
	addr = var_get_data(VAR_ID_SELF_ADDR);
	if(addr >= CFG_PARALLEL_NUM)
		addr = 0;

    master_data_reg.slave_data[addr].cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
    for( i = 0;i < SLAVE_CELL_NUM; ++ i)
    {
        master_data_reg.slave_data[addr].cell_volt_buf[i] = var_get_data(VAR_ID_CELL_VOLT01 + i);
    }
    master_data_reg.slave_data[addr].max_cell_volt = var_get_data(VAR_ID_MAX_CELL_VOLT);
    master_data_reg.slave_data[addr].min_cell_volt = var_get_data(VAR_ID_MIN_CELL_VOLT);
    master_data_reg.slave_data[addr].batt_volt = var_get_data(VAR_ID_BATT_VOLT);
    ftemp = var_get_data(VAR_ID_BUS_CURR) * VAR_CURR_FACTOR - VAR_CURR_OFFSET;
    s_curr = ftemp * 100;
    master_data_reg.slave_data[addr].curr_h16 = s_curr >> 16;
    master_data_reg.slave_data[addr].curr_l16 = s_curr & 0xffff;
    ftemp = var_get_data(VAR_ID_MAX_TEMP_VAL) * 0.1 - 50;
    master_data_reg.slave_data[addr].max_temp = (int32_t)((ftemp + 273.15f) * 10);
    ftemp = var_get_data(VAR_ID_MIN_TEMP_VAL) * 0.1 - 50;
    master_data_reg.slave_data[addr].min_temp = (int32_t)((ftemp + 273.15f) * 10);
    master_data_reg.slave_data[addr].full_cap = param_get_data(PAR_ID_FULL_CAP);
    master_data_reg.slave_data[addr].real_cap = var_get_data(VAR_ID_DISP_RCAP);
    master_data_reg.slave_data[addr].cycle = param_get_data(PAR_ID_CYCLE);
    master_data_reg.slave_data[addr].soc = var_get_data(VAR_ID_DISP_SOC) * 0.01;
    master_data_reg.slave_data[addr].soh = param_get_data(PAR_ID_SOH);
    master_data_reg.slave_data[addr].prp_volt_status.prp_msg = parallel_get_volt_prp_msg();
    master_data_reg.slave_data[addr].prp_temp_status.prp_msg = parallel_get_temp_prp_msg();
    master_data_reg.slave_data[addr].fet_status = parallel_get_fet_status();
    master_data_reg.slave_data[addr].alarm_status = parallel_get_alarm_status();
    for(i = 0;i < 15; ++ i)
    {
        master_data_reg.slave_data[addr].sn_code[i] = param_get_data(PAR_ID_SN_CODE + i);
    }
    /* 要调换高低字节 所以版本号与最后一位调换 */
	master_data_reg.slave_data[addr].sop_cc = var_get_data(VAR_ID_SOP_CC);
	master_data_reg.slave_data[addr].sop_dc = var_get_data(VAR_ID_SOP_DC);
	master_data_reg.slave_data[addr].ver_test = SOFT_VER_TEST;
	master_data_reg.slave_data[addr].version = SOFT_VER_RELEASE;
	master_data_reg.slave_data[addr].temp_num = param_get_data(PAR_ID_CB_TEMP_NUM);	
	for( i = 0;i < CFG_TEMP_NUM; ++ i)
	{
		master_data_reg.slave_data[addr].cell_temp_buf[i] = var_get_data(VAR_ID_CELL_TEMP01 + i) + 2231;
	}
	master_data_reg.slave_data[addr].mos_temp = var_get_data(VAR_ID_MOS_TEMP) + 2231;
	master_data_reg.slave_data[addr].env_temp = var_get_data(VAR_ID_ENV_TEMP) + 2231;
	slave_ol_data[addr].ol_state = 1;
	
	master_data_reg.cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
	master_data_reg.parallel_num = 1;
	
	for( j = 0;j < master_data_reg.cell_num; ++ j)
	{
		var_set_data(VAR_ID_TP_AVG_CV01 + j , var_get_data(VAR_ID_CELL_VOLT01 + j));
	}
	
	for( j = 0;(j < master_data_reg.slave_data[0].temp_num) && (j < SLAVE_TEMP_NUM); ++ j)
	{
		master_data_reg.avg_temp_buf[j] = var_get_data(VAR_ID_CELL_TEMP01 + j) + 2231; 
	}
	
	master_data_reg.avg_max_volt = var_get_data(VAR_ID_MAX_CELL_VOLT);
	master_data_reg.avg_min_volt = var_get_data(VAR_ID_MIN_CELL_VOLT);
	master_data_reg.avg_batt_volt = var_get_data(VAR_ID_BATT_VOLT);
	master_data_reg.total_bus_curr = var_get_data(VAR_ID_BUS_CURR) - 30000;
	master_data_reg.avg_max_temp = var_get_data(VAR_ID_MAX_TEMP_VAL) + 2231;
	master_data_reg.avg_min_temp = var_get_data(VAR_ID_MIN_TEMP_VAL) + 2231;
	master_data_reg.avg_soc = var_get_data(VAR_ID_DISP_SOC) * 0.01;
	master_data_reg.avg_soh = param_get_data(PAR_ID_SOH);
	master_data_reg.com_err_state = (1 << (addr - 1));
	master_data_reg.max_temp_val = var_get_data(VAR_ID_MAX_TEMP_VAL) + 2231;
	master_data_reg.min_temp_val = var_get_data(VAR_ID_MIN_TEMP_VAL) + 2231;
	master_data_reg.total_std_cap = param_get_data(PAR_ID_STD_CAP);
	/* 更新系统保护状态，只有全部发生才上报 */
	master_data_reg.total_prp_msg.bit.cov = diag_get_prp(PRP_ID_COV);					
	master_data_reg.total_prp_msg.bit.cuv = diag_get_prp(PRP_ID_CUV);
	master_data_reg.total_prp_msg.bit.ocd = diag_get_prp(PRP_ID_OCD);	
	master_data_reg.total_prp_msg.bit.ocd2 = diag_get_prp(PRP_ID_OCD2);
	master_data_reg.total_prp_msg.bit.occ = diag_get_prp(PRP_ID_OCC);
	master_data_reg.total_prp_msg.bit.sc = diag_get_prp(PRP_ID_SC);
	master_data_reg.total_prp_msg.bit.buv = diag_get_prp(PRP_ID_BUV);
	master_data_reg.total_prp_msg.bit.bov = diag_get_prp(PRP_ID_BOV);			
	master_data_reg.total_prp_msg.bit.utc = diag_get_prp(PRP_ID_UTC);
	master_data_reg.total_prp_msg.bit.otc = diag_get_prp(PRP_ID_OTC);	
	master_data_reg.total_prp_msg.bit.utd = diag_get_prp(PRP_ID_UTD);
	master_data_reg.total_prp_msg.bit.otd = diag_get_prp(PRP_ID_OTD);
	master_data_reg.total_prp_msg.bit.otm = diag_get_prp(PRP_ID_OTM);
	master_data_reg.total_prp_msg.bit.ute = diag_get_prp(PRP_ID_UTE);			
	master_data_reg.total_prp_msg.bit.tol = diag_get_prp(PRP_ID_TOL);
	master_data_reg.total_prp_msg.bit.fcmos = diag_get_prp(PRP_ID_FT_CMOS);
	master_data_reg.total_prp_msg.bit.fdmos = diag_get_prp(PRP_ID_FT_DMOS);
	master_data_reg.total_prp_msg.bit.col = diag_get_prp(PRP_ID_COL);
	master_data_reg.total_prp_msg.bit.afe_err = diag_get_prp(PRP_ID_FT_AFE);
	master_data_reg.total_prp_msg.bit.vdiff = diag_get_prp(PRP_ID_VDIFF);
	
    master_data_reg.max_volt_sn = var_get_data(VAR_ID_MAX_CELL_SN) + ((addr + 1) << 8);
	master_data_reg.min_volt_sn = var_get_data(VAR_ID_MIN_CELL_SN) + ((addr + 1) << 8);
	master_data_reg.max_temp_sn = var_get_data(VAR_ID_MAX_TEMP_SN) + ((addr + 1) << 8);
	master_data_reg.min_temp_sn = var_get_data(VAR_ID_MIN_TEMP_SN) + ((addr + 1) << 8);

	/* MOS状态 */
	fet_status = 0;
	if(var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_CHG))
		fet_status |= 0x02;
	if(var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_DSG))
		fet_status |= 0x01;
	master_data_reg.fet_status = fet_status;
	master_data_reg.total_full_cap = param_get_data(PAR_ID_FULL_CAP);
	master_data_reg.total_real_cap = var_get_data(VAR_ID_DISP_RCAP);
	master_data_reg.total_std_cap = param_get_data(PAR_ID_STD_CAP);
    master_data_reg.avg_cycle = param_get_data(PAR_ID_CYCLE);
	
	var_set_data(VAR_ID_TP_VOLT , master_data_reg.avg_batt_volt);
	var_set_data(VAR_ID_TP_CURR_H , master_data_reg.total_bus_curr >> 16);
	var_set_data(VAR_ID_TP_CURR_L , master_data_reg.total_bus_curr & 0xffff);
	var_set_data(VAR_ID_TP_REAL_CAP , master_data_reg.total_real_cap);
    var_set_data(VAR_ID_TP_FULL_CAP , master_data_reg.total_full_cap);
	var_set_data(VAR_ID_TP_SOP_CC , var_get_data(VAR_ID_SOP_CC));
    var_set_data(VAR_ID_TP_SOP_DC , var_get_data(VAR_ID_SOP_DC));
	if(var_get_data(VAR_ID_TP_SOP_CC) > 0)
	{
		var_set_data(VAR_ID_TP_SOP_CV , var_get_data(VAR_ID_SOP_CV));
	}
	else
	{
		v16_temp = param_get_data(PAR_ID_CB_CELL_NUM) * param_get_data(PAR_ID_COV_PRP_RCV) * 0.01;
		var_set_data(VAR_ID_TP_SOP_CV , v16_temp);
	}
    var_set_data(VAR_ID_TP_SOP_DV , var_get_data(VAR_ID_SOP_DV));
	var_set_data(VAR_ID_TP_CURR_H , master_data_reg.total_bus_curr >> 16);
    var_set_data(VAR_ID_TP_CURR_L , master_data_reg.total_bus_curr & 0xffff);
    var_set_data(VAR_ID_TP_SOC , master_data_reg.avg_soc);
    var_set_data(VAR_ID_TP_SOH , master_data_reg.avg_soh);
    var_set_data(VAR_ID_TP_PACK_OL_ST , master_data_reg.com_err_state);
    var_set_data(VAR_ID_TP_AVG_TEMP , var_get_data(VAR_ID_AGV_TEMP) + 2231);
    var_set_data(VAR_ID_TP_CYCLE , master_data_reg.avg_cycle);
	var_set_data(VAR_ID_TP_AVG_BV , master_data_reg.avg_batt_volt ); 
    var_set_data(VAR_ID_TP_MAXC_VOLT,master_data_reg.avg_max_volt);			
	var_set_data(VAR_ID_TP_MINC_VOLT,master_data_reg.avg_min_volt);	
    var_set_data(VAR_ID_TP_MAXT_VAL,var_get_data(VAR_ID_MAX_TEMP_VAL) + 2231);			
	var_set_data(VAR_ID_TP_MINT_VAL,var_get_data(VAR_ID_MIN_TEMP_VAL) + 2231);	
	var_set_data(VAR_ID_TP_MAXC_SN,master_data_reg.max_volt_sn);
	var_set_data(VAR_ID_TP_MINC_SN,master_data_reg.min_volt_sn);
	var_set_data(VAR_ID_TP_MAXT_SN,master_data_reg.max_temp_sn);
	var_set_data(VAR_ID_TP_MINT_SN,master_data_reg.min_temp_sn);
	
	var_set_data(VAR_ID_TP_MIN_SOH , param_get_data(PAR_ID_SOH));
	var_set_data(VAR_ID_TP_AVG_MOST , var_get_data(VAR_ID_MOS_TEMP) + 2231);
	var_set_data(VAR_ID_TP_AVG_ENVT , var_get_data(VAR_ID_ENV_TEMP) + 2231);
	var_set_data(VAR_ID_TP_MIN_MOST_VAL , var_get_data(VAR_ID_MOS_TEMP) + 2231);
	var_set_data(VAR_ID_TP_MAX_MOST_VAL , var_get_data(VAR_ID_MOS_TEMP) + 2231);
	var_set_data(VAR_ID_TP_MIN_MOST_SN , 1);
	var_set_data(VAR_ID_TP_MAX_MOST_SN, 1);
	var_set_data(VAR_ID_TP_MAX_CYCLE , param_get_data(PAR_ID_CYCLE));
	var_set_data(VAR_ID_TP_MIN_ENVT_VAL , var_get_data(VAR_ID_ENV_TEMP) + 2231);
	var_set_data(VAR_ID_TP_MAX_ENVT_VAL , var_get_data(VAR_ID_ENV_TEMP) + 2231);
	var_set_data(VAR_ID_TP_MIN_ENVT_SN , 1);
	var_set_data(VAR_ID_TP_MAX_ENVT_SN, 1);	
}    

void parallel_master_calc(void)
{
    uint32_t s32temp = 0;
	uint16_t i = 0;
	uint16_t j = 0;
    uint8_t slave_ol_num = 0;
	uint32_t sum_cell_volt[CELL_MAX_NUM] = {0};
	uint32_t sum_cell_temp[CFG_TEMP_NUM] = {0};
	uint32_t sum_max_temp = 0;
	uint32_t sum_min_temp = 0;
	int32_t sum_bus_curr = 0;
	uint32_t sum_batt_volt = 0;
	uint32_t sum_soc = 0;
	uint32_t sum_soh = 0;
	slave_prp_num_type slave_prp = {0};
    uint16_t max_chg_curr = 0;
    uint16_t max_dsg_curr = 0;
	uint32_t total_full_cap = 0;
	uint32_t total_real_cap = 0;
	uint8_t fet_status = 0;
    uint32_t sum_cycle = 0;
    uint16_t slave_ol_status = 0;
	uint16_t max_cell_temp = 0;
	uint16_t min_cell_temp = 0xffff;
	uint16_t pack_minc_volt = 0;
	uint16_t pack_maxc_volt = 0;
//	uint16_t max_soh = 0;
	uint16_t min_soh = 0xffff;
	uint16_t mos_maxt = 0;
	uint16_t mos_mint = 0xffff;
	uint16_t mos_max_sn = 0;
	uint16_t mos_min_sn = 0;
	uint16_t env_maxt = 0;
	uint16_t env_mint = 0xffff;
	uint16_t env_max_sn = 0;
	uint16_t env_min_sn = 0;
	uint32_t sum_envt = 0;
	uint32_t sum_most = 0;
	uint16_t cycle_max = 0;
	uint16_t min_sop_curr = 0;
	uint16_t chg_sop_num = 0;
	uint16_t v16_temp = 0;

	pack_maxc_volt = master_data_reg.slave_data[0].cell_volt_buf[0];
	pack_minc_volt = master_data_reg.slave_data[0].cell_volt_buf[0];
	master_data_reg.parallel_num = slave_ol_num;	
    max_cell_temp = master_data_reg.slave_data[0].cell_temp_buf[0];
    min_cell_temp = master_data_reg.slave_data[0].cell_temp_buf[0];
	min_sop_curr = 0xffff;//master_data_reg.slave_data[0].sop_cc;
	for(i = 0;i < CFG_PARALLEL_NUM; ++ i)
	{ 
		if(slave_ol_data[i].ol_state)
		{
			++ slave_ol_num;
			slave_ol_status |= (1 << i);
			total_full_cap += master_data_reg.slave_data[i].full_cap;
			total_real_cap += master_data_reg.slave_data[i].real_cap;
			/* 计算平均电压 */
			for( j = 0;(j < SLAVE_CELL_NUM) && (j < master_data_reg.slave_data[i].cell_num); ++ j)
			{
				sum_cell_volt[j] += master_data_reg.slave_data[i].cell_volt_buf[j];
				if(pack_maxc_volt <= master_data_reg.slave_data[i].cell_volt_buf[j])
				{
					master_data_reg.max_volt_sn = ((i + 1) << 8) + ( j + 1 );
					pack_maxc_volt = master_data_reg.slave_data[i].cell_volt_buf[j];
				}
				if(pack_minc_volt >= master_data_reg.slave_data[i].cell_volt_buf[j])
				{
					master_data_reg.min_volt_sn = ((i + 1) << 8) + ( j + 1 );
					pack_minc_volt = master_data_reg.slave_data[i].cell_volt_buf[j];
				}
			}
			/* 计算平均温度 */
			for( j = 0;(j < SLAVE_TEMP_NUM) && (j < master_data_reg.slave_data[i].temp_num); ++ j)
			{
				sum_cell_temp[j] += master_data_reg.slave_data[i].cell_temp_buf[j];
				if(master_data_reg.slave_data[i].cell_temp_buf[j] == 2321)
					continue ;
				if(max_cell_temp <= master_data_reg.slave_data[i].cell_temp_buf[j])
				{
					master_data_reg.max_temp_sn = ((i + 1) << 8) + ( j + 1 );
					max_cell_temp = master_data_reg.slave_data[i].cell_temp_buf[j];
				}
				if(min_cell_temp >= master_data_reg.slave_data[i].cell_temp_buf[j])
				{
					master_data_reg.min_temp_sn = ((i + 1) << 8) + ( j + 1 );
					min_cell_temp = master_data_reg.slave_data[i].cell_temp_buf[j];
				}
			}
			
			if(master_data_reg.slave_data[i].soh < min_soh)
				min_soh = master_data_reg.slave_data[i].soh;
			
			if(master_data_reg.slave_data[i].cycle > cycle_max)
			cycle_max = master_data_reg.slave_data[i].cycle;
			
			sum_most += master_data_reg.slave_data[i].mos_temp;
			if(master_data_reg.slave_data[i].mos_temp < mos_mint)
			{
				mos_mint = master_data_reg.slave_data[i].mos_temp;
				mos_min_sn = ((i + 1) << 8) + 1;
			}
			if(master_data_reg.slave_data[i].mos_temp > mos_maxt)
			{
				mos_maxt = master_data_reg.slave_data[i].mos_temp;
				mos_max_sn = ((i + 1) << 8) + 1;
			}
			
			sum_envt += master_data_reg.slave_data[i].env_temp;
			if(master_data_reg.slave_data[i].env_temp < env_mint)
			{
				env_mint = master_data_reg.slave_data[i].env_temp;
				env_min_sn = ((i + 1) << 8) + 1;
			}
			if(master_data_reg.slave_data[i].env_temp > env_maxt)
			{
				env_maxt = master_data_reg.slave_data[i].env_temp;
				env_max_sn = ((i + 1) << 8) + 1;
			}
			
			/* 计算平均温度 */
			sum_max_temp += master_data_reg.slave_data[i].max_temp;
			sum_min_temp += master_data_reg.slave_data[i].min_temp;
			
			s32temp = (master_data_reg.slave_data[i].curr_h16 << 16) + master_data_reg.slave_data[i].curr_l16;
			if(master_data_reg.slave_data[i].curr_h16 & 0x8000)
			{
				sum_bus_curr -= (~s32temp + 1);
			}
			else
			{
				sum_bus_curr += s32temp;
			}
			sum_batt_volt += master_data_reg.slave_data[i].batt_volt;
			sum_soc += master_data_reg.slave_data[i].soc;
			sum_soh += master_data_reg.slave_data[i].soh;
			sum_cycle += master_data_reg.slave_data[i].cycle;
						
			if(master_data_reg.slave_data[i].prp_volt_status.name.cov)
				slave_prp.cov_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.cuv)
				slave_prp.cuv_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.ocd)
				slave_prp.ocd_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.ocd2)
				slave_prp.ocd2_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.occ)
				slave_prp.occ_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.sc)
				slave_prp.sc_cnt ++;	
			if(master_data_reg.slave_data[i].prp_volt_status.name.buv)
				slave_prp.buv_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.bov)
				slave_prp.bov_cnt ++;	
			if(master_data_reg.slave_data[i].prp_volt_status.name.col)
				slave_prp.col_cnt ++;		
			if(master_data_reg.slave_data[i].prp_volt_status.name.afe_err)
				slave_prp.afe_err_cnt ++;		
			if(master_data_reg.slave_data[i].prp_temp_status.name.utc)
				slave_prp.utc_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.otc)
				slave_prp.otc_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.utd)
				slave_prp.utd_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.otd)
				slave_prp.otd_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.otm)
				slave_prp.otm_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.ote)
				slave_prp.ote_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.ute)
				slave_prp.ute_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.tol)
				slave_prp.tol_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.cmos_ft)
				slave_prp.fcmos_cnt ++;
			if(master_data_reg.slave_data[i].prp_temp_status.name.dmos_ft)
				slave_prp.fdmos_cnt ++;
			if(master_data_reg.slave_data[i].prp_volt_status.name.vdiff)
				slave_prp.vdiff_cnt ++;
                                
			// 计算SOP 取非0最小值
			if((min_sop_curr >= master_data_reg.slave_data[i].sop_cc) && (master_data_reg.slave_data[i].sop_cc != 0))
			{
				min_sop_curr = master_data_reg.slave_data[i].sop_cc;
			}
			
			if(master_data_reg.slave_data[i].sop_cc != 0)
				chg_sop_num ++;
			
			max_chg_curr += master_data_reg.slave_data[i].sop_cc;
			max_dsg_curr += master_data_reg.slave_data[i].sop_dc;
            if(master_data_reg.slave_data[i].fet_status & 0x01) /* 放电MOS */
            {
				fet_status |= 0x01;
            }
            if(master_data_reg.slave_data[i].fet_status & 0x02) /* 充电MOS */
            {
				fet_status |= 0x02;
            }
		}
		else
		{
			;
		}
	}

	master_data_reg.cell_num = param_get_data(PAR_ID_CB_CELL_NUM);
	master_data_reg.parallel_num = slave_ol_num;
	if(master_data_reg.cell_num >= CELL_MAX_NUM)
		master_data_reg.cell_num = CELL_MAX_NUM;
	
	for( j = 0;j < master_data_reg.cell_num; ++ j)
	{
		master_data_reg.avg_cell_buf[j] = sum_cell_volt[j] / slave_ol_num; 
		var_set_data(VAR_ID_TP_AVG_CV01 + j , master_data_reg.avg_cell_buf[j]);
	}
	
	for( j = 0;(j < master_data_reg.slave_data[0].temp_num) && (j < SLAVE_TEMP_NUM); ++ j)
	{
		master_data_reg.avg_temp_buf[j] = sum_cell_temp[j] / slave_ol_num; 
	}
	master_data_reg.avg_max_volt = pack_maxc_volt;
	master_data_reg.avg_min_volt = pack_minc_volt;
	master_data_reg.avg_batt_volt = sum_batt_volt/slave_ol_num;
	master_data_reg.total_bus_curr = sum_bus_curr;
	master_data_reg.avg_max_temp = sum_max_temp/slave_ol_num;
	master_data_reg.avg_min_temp = sum_min_temp/slave_ol_num;
	master_data_reg.avg_soc = (sum_soc/slave_ol_num)+0.5;
	if(master_data_reg.avg_soc > 100)
		master_data_reg.avg_soc = 100;
	master_data_reg.avg_soh = sum_soh/slave_ol_num;
	if(master_data_reg.avg_soh > 100)
		master_data_reg.avg_soh = 100;	
	master_data_reg.com_err_state = slave_ol_status;
	master_data_reg.max_temp_val = max_cell_temp;
	master_data_reg.min_temp_val = min_cell_temp;
	master_data_reg.total_std_cap = param_get_data(PAR_ID_STD_CAP)*slave_ol_num;
	/* 更新系统保护状态，只有全部发生才上报 */
	master_data_reg.total_prp_msg.bit.cov = (slave_ol_num == slave_prp.cov_cnt) ? 1 : 0;					
	master_data_reg.total_prp_msg.bit.cuv = (slave_ol_num == slave_prp.cuv_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.ocd = (slave_ol_num == slave_prp.ocd_cnt) ? 1 : 0;	
	master_data_reg.total_prp_msg.bit.ocd2 = (slave_ol_num == slave_prp.ocd2_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.occ = (slave_ol_num == slave_prp.occ_cnt) ? 1 : 0;	
	master_data_reg.total_prp_msg.bit.sc = (slave_prp.sc_cnt > 0) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.buv = (slave_ol_num == slave_prp.buv_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.bov = (slave_ol_num == slave_prp.bov_cnt) ? 1 : 0;			
	master_data_reg.total_prp_msg.bit.utc = (slave_ol_num == slave_prp.utc_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.otc = (slave_ol_num == slave_prp.otc_cnt) ? 1 : 0;			
	master_data_reg.total_prp_msg.bit.utd = (slave_ol_num == slave_prp.utd_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.otd = (slave_ol_num == slave_prp.otd_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.otm = (slave_ol_num == slave_prp.otm_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.ote = (slave_ol_num == slave_prp.ote_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.ute = (slave_ol_num == slave_prp.ute_cnt) ? 1 : 0;			
	master_data_reg.total_prp_msg.bit.tol = (slave_ol_num == slave_prp.tol_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.fcmos = (slave_prp.fcmos_cnt > 0) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.fdmos = (slave_prp.fdmos_cnt > 0) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.col = (slave_ol_num == slave_prp.col_cnt) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.afe_err = (slave_prp.afe_err_cnt > 0) ? 1 : 0;
	master_data_reg.total_prp_msg.bit.vdiff = (slave_ol_num == slave_prp.vdiff_cnt) ? 1 : 0;
	// 如果任一系统发生AFE故障、短路保护、充电MOS故障，立即停止整机充放，限制充放电需求电流为0，禁止充放。
	max_chg_curr = chg_sop_num * min_sop_curr;
	if(master_data_reg.total_prp_msg.bit.sc || master_data_reg.total_prp_msg.bit.fcmos||master_data_reg.total_prp_msg.bit.fdmos)
	{
		//max_chg_curr = 0;
		max_dsg_curr = 0;
	}
	/* MOS状态 */
	master_data_reg.fet_status = fet_status;

	master_data_reg.total_full_cap = total_full_cap;

	master_data_reg.total_real_cap = total_real_cap;

	master_data_reg.total_std_cap = total_full_cap;
    master_data_reg.avg_cycle = sum_cycle/slave_ol_num;
	
	var_set_data(VAR_ID_TP_VOLT , master_data_reg.avg_batt_volt);
	var_set_data(VAR_ID_TP_CURR_H , master_data_reg.total_bus_curr >> 16);
	var_set_data(VAR_ID_TP_CURR_L , master_data_reg.total_bus_curr & 0xffff);
	var_set_data(VAR_ID_TP_REAL_CAP , total_real_cap);
    var_set_data(VAR_ID_TP_FULL_CAP , total_full_cap);
	var_set_data(VAR_ID_TP_SOP_CC , max_chg_curr);
    var_set_data(VAR_ID_TP_SOP_DC , max_dsg_curr);
	// 如果充电需求电流为0，则降低需求电流，解决逆变器不判断充电需求电流问题。
	if(max_chg_curr > 0)
	{
		var_set_data(VAR_ID_TP_SOP_CV , var_get_data(VAR_ID_SOP_CV));
	}
	else
	{
		v16_temp = param_get_data(PAR_ID_CB_CELL_NUM) * param_get_data(PAR_ID_COV_PRP_RCV) * 0.01;
		var_set_data(VAR_ID_TP_SOP_CV , v16_temp);
	}
	
    var_set_data(VAR_ID_TP_SOP_DV , var_get_data(VAR_ID_SOP_DV));
	var_set_data(VAR_ID_TP_CURR_H , sum_bus_curr >> 16);
    var_set_data(VAR_ID_TP_CURR_L , sum_bus_curr & 0xffff);
    var_set_data(VAR_ID_TP_SOC , master_data_reg.avg_soc);
    var_set_data(VAR_ID_TP_SOH , master_data_reg.avg_soh);
    var_set_data(VAR_ID_TP_PACK_OL_ST , slave_ol_status);
    var_set_data(VAR_ID_TP_AVG_TEMP , (master_data_reg.avg_max_temp + master_data_reg.avg_min_temp) / 2);
    var_set_data(VAR_ID_TP_CYCLE , master_data_reg.avg_cycle);
	var_set_data(VAR_ID_TP_AVG_BV , master_data_reg.avg_batt_volt ); 
    var_set_data(VAR_ID_TP_MAXC_VOLT,master_data_reg.avg_max_volt);			
	var_set_data(VAR_ID_TP_MINC_VOLT,master_data_reg.avg_min_volt);	
    var_set_data(VAR_ID_TP_MAXT_VAL,max_cell_temp);			
	var_set_data(VAR_ID_TP_MINT_VAL,min_cell_temp);	
	var_set_data(VAR_ID_TP_MAXC_SN,master_data_reg.max_volt_sn);
	var_set_data(VAR_ID_TP_MINC_SN,master_data_reg.min_volt_sn);
	var_set_data(VAR_ID_TP_MAXT_SN,master_data_reg.max_temp_sn);
	var_set_data(VAR_ID_TP_MINT_SN,master_data_reg.min_temp_sn);
	
	var_set_data(VAR_ID_TP_MIN_SOH , min_soh);
	var_set_data(VAR_ID_TP_AVG_MOST , sum_most / master_data_reg.parallel_num);
	var_set_data(VAR_ID_TP_AVG_ENVT , sum_envt / master_data_reg.parallel_num);
	var_set_data(VAR_ID_TP_MIN_MOST_VAL , mos_mint);
	var_set_data(VAR_ID_TP_MAX_MOST_VAL , mos_maxt);
	var_set_data(VAR_ID_TP_MIN_MOST_SN , mos_min_sn);
	var_set_data(VAR_ID_TP_MAX_MOST_SN, mos_max_sn);
	var_set_data(VAR_ID_TP_MAX_CYCLE , cycle_max);
	var_set_data(VAR_ID_TP_MIN_ENVT_VAL , env_mint);
	var_set_data(VAR_ID_TP_MAX_ENVT_VAL , env_maxt);
	var_set_data(VAR_ID_TP_MIN_ENVT_SN , env_min_sn);
	var_set_data(VAR_ID_TP_MAX_ENVT_SN, env_max_sn);	
}

void parallel_clear_slave(uint8_t slave)
{
    uint16_t i = 0;
    uint16_t *p_buf = NULL;
    uint16_t len = 0;

    if(slave > CFG_PARALLEL_NUM)
        return ;
    
    p_buf = (uint16_t *)&master_data_reg.slave_data[slave];

    len = sizeof(slave_data_type)/sizeof(uint16_t);
    for( i = 0;i < len ; ++ i)
    {
        p_buf[i] = 0;
    }
}

uint16_t parallel_get_volt_prp_msg(void)
{
    slave_vlot_prp_type prp_msg = {0};
    prp_msg.name.cov = diag_get_prp(PRP_ID_COV);
	prp_msg.name.cuv = diag_get_prp(PRP_ID_CUV);
	prp_msg.name.occ = diag_get_prp(PRP_ID_OCC);
	prp_msg.name.ocd = diag_get_prp(PRP_ID_OCD);
	prp_msg.name.ocd2 = diag_get_prp(PRP_ID_OCD2);
	prp_msg.name.bov = diag_get_prp(PRP_ID_BOV);
	prp_msg.name.buv = diag_get_prp(PRP_ID_BUV);
	prp_msg.name.col = diag_get_prp(PRP_ID_COL);
	prp_msg.name.afe_err = diag_get_prp(PRP_ID_FT_AFE);
	prp_msg.name.vdiff = diag_get_prp(PRP_ID_VDIFF);
    prp_msg.name.full_chg = diag_get_alarm(ALM_ID_FCHG);
	prp_msg.name.reverse = diag_get_prp(PRP_ID_FT_REVERSE);	
	
    return prp_msg.prp_msg;
}

uint16_t parallel_get_temp_prp_msg(void)
{
    slave_temp_prp_type prp_msg = {0};

	prp_msg.name.utc = diag_get_prp(PRP_ID_UTC);
	prp_msg.name.otc = diag_get_prp(PRP_ID_OTC);
	prp_msg.name.utd = diag_get_prp(PRP_ID_UTD);
	prp_msg.name.otd = diag_get_prp(PRP_ID_OTD);
	prp_msg.name.otm = diag_get_prp(PRP_ID_OTM);
	prp_msg.name.ote = diag_get_prp(PRP_ID_OTE);
	prp_msg.name.ute = diag_get_prp(PRP_ID_UTE);
	prp_msg.name.cmos_ft = diag_get_prp(PRP_ID_FT_CMOS);
	prp_msg.name.dmos_ft = diag_get_prp(PRP_ID_FT_DMOS);
	prp_msg.name.tol=diag_get_prp(PRP_ID_TOL);
    
    return prp_msg.prp_msg;
}

uint16_t parallel_get_fet_status(void)
{
    uint8_t fet_state = 0;
    uint8_t read_data = 0;

    read_data = var_get_data(VAR_ID_MOS_STATE);
	
    if(read_data & (1 << VAR_MOS_ST_DSG))
        fet_state |= (1 << 0);	
    if(read_data & (1 << VAR_MOS_ST_CHG))
        fet_state |= (1 << 1);
	
    read_data = var_get_data(VAR_ID_CURR_DR);
    if(read_data == CURR_DR_DSG)
        fet_state |= (1 << 2);
    else if(read_data == CURR_DR_CHG)
        fet_state |= (1 << 3);

	if(DO_OUT_ON == If_do_get_out_state(DO_LIMIT_10A))
        fet_state |= (1 << 4);
	if(DO_OUT_ON == If_do_get_out_state(DO_RLY_FAULT))
        fet_state |= (1 << 5);
	if(DO_OUT_ON == If_do_get_out_state(DO_RLY_SOCL))
        fet_state |= (1 << 6);
	if(DO_OUT_ON == If_do_get_out_state(DO_FAN_CTRL))
        fet_state |= (1 << 7);
	if(DO_OUT_ON == If_do_get_out_state(DO_HOT_CTRL))
        fet_state |= (1 << 8);
	if(DO_OUT_ON == If_do_get_out_state(DO_PCHG_CTRL))
        fet_state |= (1 << 9);
	
	if(DI_IN_ON == If_di_read_in(DI_CHG_SIGN))
        fet_state |= (1 << 10);
	if(DI_IN_ON == If_di_read_in(DI_LOAD_SIGN))
        fet_state |= (1 << 11);
	if(DI_IN_ON == If_di_read_in(DI_SW_SIGN))
        fet_state |= (1 << 12);
  
    return fet_state;
}

uint16_t parallel_get_alarm_status(void)
{
    uint32_t alm_msg = 0;
    if(diag_get_alarm(ALM_ID_COV))
        alm_msg |= (1 << 0);
    if(diag_get_alarm(ALM_ID_CUV))
        alm_msg |= (1 << 1);
    if(diag_get_alarm(ALM_ID_OCD))
        alm_msg |= (1 << 2);
    if(diag_get_alarm(ALM_ID_OCC))
        alm_msg |= (1 << 3);
    if(diag_get_alarm(ALM_ID_BOV))
        alm_msg |= (1 << 4);
    if(diag_get_alarm(ALM_ID_BUV))
        alm_msg |= (1 << 5);
    if(diag_get_alarm(ALM_ID_OTC))
        alm_msg |= (1 << 6);
    if(diag_get_alarm(ALM_ID_UTC))
        alm_msg |= (1 << 7);
    if(diag_get_alarm(ALM_ID_OTD))
        alm_msg |= (1 << 8);
    if(diag_get_alarm(ALM_ID_UTD))
        alm_msg |= (1 << 9);
    if(diag_get_alarm(ALM_ID_OTM))
        alm_msg |= (1 << 10);
    if(diag_get_alarm(ALM_ID_SOCL))
        alm_msg |= (1 << 11);
	if(diag_get_alarm(ALM_ID_OTE))
        alm_msg |= (1 << 12);
	if(diag_get_alarm(ALM_ID_UTE))
        alm_msg |= (1 << 13);
	if(diag_get_alarm(ALM_ID_VDIFF))
        alm_msg |= (1 << 14);
	if(diag_get_alarm(ALM_ID_FCHG))
        alm_msg |= (1 << 15);
	
    return alm_msg;
}

uint8_t parallel_get_mode(void)
{
#ifdef PARALLEL_MODE_DSW
	var_set_data(VAR_ID_SELF_ADDR , If_di_read_addr());
	
	return PAL_MODE_SW_RS485;
#endif
	
	uint8_t addr = 0;

	addr = If_di_read_addr();
	if(0 != addr)
	{
		var_set_data(VAR_ID_SELF_ADDR , addr);
		return PAL_MODE_SW_RS485;
	}
	else 
	{
		return PAL_MODE_AUTO_RS485;
	}
}

void parallel_pcs_deal(void)
{
	uint8_t now_soc = 0;
	now_soc = var_get_data(VAR_ID_DISP_SOC) * 0.01;
	
	if(var_get_data(VAR_ID_TP_SOP_CC) > 0)
	{
		chg_en_flag = 1;
	}
	else
	{
		chg_en_flag = 0;
	}
	if(var_get_data(VAR_ID_TP_SOP_DC) > 0)
	{
		dsg_en_flag = 1;
	}
	else
	{
		dsg_en_flag = 0;
	}
	
	now_soc = var_get_data(VAR_ID_TP_SOC);
	
	if(now_soc >= 14)
	{
		force_chg1 = 0;
		force_chg2 = 0;
	}
	else
	{
		if(now_soc < 10)
		{
			force_chg2 = 1;
		}
		if(now_soc < 10)
		{
			force_chg1 = 1;
		}
	}
}

uint8_t parallel_get_pcs_ctrl(uint8_t name)
{
	if(name == PARALLEL_PCS_CHG_EN)
		return chg_en_flag;
	if(name == PARALLEL_PCS_DSG_EN)
		return dsg_en_flag;
	if(name == PARALLEL_PCS_FROCE_CHG1)
		return force_chg1;
	if(name == PARALLEL_PCS_FROCE_CHG2)
		return force_chg2;
	
	return 0;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */


/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
